﻿using System.Xml;

namespace SdmxMl.Common
{
    /// <summary>
    /// Helper Class to read an internationalized text in SDMX document
    /// </summary>
    class MultiLangNodeReader
    {
        #region internal members

        public string[] arrText;

        #endregion

        #region C'tor

        public MultiLangNodeReader()
        {
            arrText = new string[LangSupport.Count];
        }
        #endregion

        #region XML Read

        public void Read(MultiLang ml, XmlNode nodeCode, string tag, XmlNamespaceManager nsmgr, bool fillEmptyLang)
        {
            string ns = "structure";
            SdmxNamespaceManager sdmxNsmgr = nsmgr as SdmxNamespaceManager;
            if (sdmxNsmgr != null && sdmxNsmgr.VersionSdmx == SdmxVersion.SDMX_21)
                ns = "common";

            Read(ml, nodeCode, tag, ns, nsmgr, fillEmptyLang);
        }

        public void Read(MultiLang ml, XmlNode nodeCode, string tag, string ns, XmlNamespaceManager nsmgr, bool fillEmptyLang)
        {
            Init();
            string sdmxDefault = string.Empty;
            if (nodeCode != null && ml != null)
            {
                int ilg = 0;
                foreach (string lg in LangSupport.SupportedLanguages)
                {
                    string query = string.Format("./{2}:{1}[@xml:lang='{0}']", lg, tag, ns);
                    XmlNodeList nodeList = nodeCode.SelectNodes(query, nsmgr);
                    if (nodeList.Count > 0)
                        arrText[ilg] = nodeList[0].InnerText;
                    ++ilg;
                }

                if (AllEmpty())
                {
                    // Try with no language type
                    string query = string.Format("./{1}:{0}[not(@xml:lang)]", tag, ns);
                    XmlNodeList nodeList = nodeCode.SelectNodes(query, nsmgr);
                    if (nodeList.Count > 0)
                    {
                        if (TextCompression.Expand)
                        {
                            for (int i = 0; i < arrText.Length; i++)
                                arrText[i] = nodeList[0].InnerText;
                        }
                        else
                        {
                            // This goes for english (SDMX default if no language specified
                            sdmxDefault = nodeList[0].InnerText;
                        }
                    }
                }

                // If requested fill missing languages
                if (fillEmptyLang)
                    for (int i = 0; i < arrText.Length; i++)
                        if (arrText[i].Length == 0)
                            arrText[i] = FirstFilled();
            }

            Update(ml);
            if (sdmxDefault.Length > 0)
                ml.UpdateForLanguage("en", sdmxDefault);
        }
        #endregion

        #region Private methods

        /// <summary>Default all texts</summary>
        private void Init()
        {
            for (int i = 0; i < arrText.Length; i++)
                arrText[i] = string.Empty;
        }

        /// <summary>Check if text exist in at least one language </summary>
        /// <returns>True if none</returns>
        private bool AllEmpty()
        {
            bool all = true;
            for (int i = 0; i < arrText.Length; i++)
                if (arrText[i].Length > 0)
                {
                    all = false;
                    break;
                }
            return all;
        }

        /// <summary>get a filled text</summary>
        /// <returns>First filled lang or question mark if nothing available</returns>
        private string FirstFilled()
        {
            string first = "?";
            for (int i = 0; i < arrText.Length; i++)
                if (arrText[i].Length > 0)
                {
                    first = arrText[i];
                    break;
                }

            return first;
        }

        private void Update(MultiLang ml)
        {
            ml.TextList.Clear();
            int i = 0;
            foreach (string lg in LangSupport.SupportedLanguages)
            {
                if (arrText[i].Length > 0)
                    ml.TextList.Add(new TextType(lg, arrText[i]));
                ++i;
            }
        }
        #endregion
    }

}
